﻿using System;
using System.Collections.Generic;
using ParserGenerator.Collections;
using ParserGenerator.GrammarConstruction;
using ParserGenerator.SyntacticAnalysis;

namespace ParserGenerator.ScannerConstruction
{
    [Serializable]
    public sealed class ScannerAutomatonReductions : ReadOnlySet<LexicalRuleDeclarator>
    {
        public ScannerAutomatonState State { get; }

        internal ScannerAutomatonReductions(ScannerAutomatonState state)
            : base(new HashSet<LexicalRuleDeclarator>())
        {
            if (state == null)
                throw new ArgumentNullException(nameof(state));
            State = state;
        }

        internal bool Add(LexicalRuleDeclarator rule)
        {
            if (rule == null)
                throw new ArgumentNullException(nameof(rule));
            return Set.Add(rule);
        }

        internal void ApplyLiteralFirstResolutions()
        {
            if (Set.Count <= 1)
                return;
            ScannerAutomatonStateTable table = State.Table;
            GrammarTerminalTable tokens = table.ScannerAutomaton.Tokens;
            LexicalRuleDeclarator rule = null;
            foreach (LexicalRuleDeclarator r in Set)
            {
                GrammarTerminalSymbol token = tokens.TryGetToken(r, false);
                if (token != null && token.IsLiteral)
                {
                    if (rule != null)
                        return;
                    rule = r;
                }
                else if (r.Pattern.IsQuoteString || r.Pattern.IsString)
                {
                    if (rule != null)
                        return;
                    rule = r;
                }
            }
            if (rule == null)
                return;
            Set.Clear();
            Set.Add(rule);
        }
    }
}
